package com.event.management.frontend.common;

import lombok.Data;
import java.io.Serializable;
import java.util.List;

/**
 * 统一响应结果封装类
 * @param <T> 数据类型
 */
@Data
public class Result<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 状态码：200-成功，非200-失败
     */
    private Integer code;
    
    /**
     * 响应消息
     */
    private String msg;
    
    /**
     * 响应数据
     */
    private T data;

    /**
     * 无参构造函数
     */
    public Result() {
        // 默认构造函数
    }

    /**
     * 成功返回结果
     */
    public static <T> Result<T> ok() {
        return ok(null);
    }

    /**
     * 成功返回结果
     * @param data 数据
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> ok(T data) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMsg("操作成功");
        result.setData(data);
        return result;
    }

    /**
     * 成功返回结果
     * @param data 数据
     * @param message 消息
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> ok(T data, String message) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMsg(message);
        result.setData(data);
        return result;
    }

    /**
     * 失败返回结果
     * @param message 错误消息
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> fail(String message) {
        return fail(400, message);
    }

    /**
     * 失败返回结果
     * @param code 错误码
     * @param message 错误消息
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> fail(Integer code, String message) {
        Result<T> result = new Result<>();
        result.setCode(code);
        result.setMsg(message);
        return result;
    }
    
    /**
     * 失败返回结果（带数据）
     * @param code 错误码
     * @param message 错误消息
     * @param data 错误数据
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> fail(Integer code, String message, T data) {
        Result<T> result = new Result<>();
        result.setCode(code);
        result.setMsg(message);
        result.setData(data);
        return result;
    }

    /**
     * 参数验证失败返回结果
     * @param message 错误消息
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> validateFailed(String message) {
        return fail(400, message);
    }

    /**
     * 未登录返回结果
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> unauthorized() {
        return fail(401, "请先登录后再操作");
    }

    /**
     * 未授权返回结果
     * @param <T> 数据类型
     * @return 响应结果
     */
    public static <T> Result<T> forbidden() {
        return fail(403, "没有相关权限");
    }
    
    /**
     * 分页数据结果
     */
    @Data
    public static class Page<T> implements Serializable {
    
        private static final long serialVersionUID = 2L;
        
        /**
         * 总记录数
         */
        private Long total;
        
        /**
         * 当前页数据列表
         */
        private List<T> records;
        
        /**
         * 当前页码
         */
        private Integer current;
        
        /**
         * 每页大小
         */
        private Integer size;
        
        /**
         * 无参构造函数
         */
        public Page() {
            // 默认构造函数
        }
    }
    
    /**
     * 创建分页结果
     * @param records 记录列表
     * @param total 总数
     * @param <T> 数据类型
     * @return 分页响应结果
     */
    public static <T> Result<Page<T>> page(List<T> records, Long total) {
        Page<T> page = new Page<>();
        page.setRecords(records);
        page.setTotal(total);
        return ok(page);
    }
    
    /**
     * 创建分页结果
     * @param records 记录列表
     * @param total 总数
     * @param current 当前页码
     * @param size 每页大小
     * @param <T> 数据类型
     * @return 分页响应结果
     */
    public static <T> Result<Page<T>> page(List<T> records, Long total, Integer current, Integer size) {
        Page<T> page = new Page<>();
        page.setRecords(records);
        page.setTotal(total);
        page.setCurrent(current);
        page.setSize(size);
        return ok(page);
    }
} 